package controllers

import (
	"bytes"
	"database/sql"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/dchest/captcha"
	"github.com/json-iterator/go"
	"nspel/entity"
	"nspel/model"
	"nspel/nspel"
	"nspel/service"
	"nspel/util"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

type UserController struct {
	beego.Controller
	service.UsersService
}

func (c *UserController) PostLogin() {
	defer c.ServeJSON()
	var arg model.PostLogin
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &arg)
	captchaId, ok := c.Ctx.Input.Session("cid").(string)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "无验证码"}
		return
	}
	if !captcha.VerifyString(captchaId, arg.Captcha) {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "验证码错误"}
		return
	}
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求参数错误"}
		return
	} else {
		status, authority, uid, err := c.Login(arg)
		if err != nil {
			nspel.Error(err)
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			return
		} else if status == true {
			c.SetSession("uid", uid)
			c.SetSession("authority", authority)
			resData := new(model.PostLoginRes)
			err := resData.GetUserInfo(authority, uid, arg.UserName)
			if err != nil {
				nspel.Error(err)
				c.Data["json"] = model.ErrorRes{RetCode: 3, Msg: "服务器运行错误"}
				return
			} else {
				c.Data["json"] = resData
				return
			}
		} else {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "验证失败"}
			return
		}
	}
}

func (c *UserController) PostLogout() {
	c.DestroySession()
	c.Data["json"] = map[string]int64{"retCode": 0}
	c.ServeJSON()
}

func (c *UserController) PostUserNameValidateExist() {
	defer c.ServeJSON()
	var requestData model.PostUserNameValidateExist
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestData)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
		return
	}
	b, err := requestData.Validate()
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
		return
	}
	if requestData.AuthorityByte == entity.ManagerAuthority.Area {
		area := new(entity.Area)
		err = area.SelectAllById(requestData.Id)
		if err != nil {
			if err == orm.ErrNoRows {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
				return
			} else {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			}
		}
		if area.UserId.Valid {
			manage := new(entity.Manager)
			err = manage.SelectAllById(area.UserId.Int64)
			if err != nil && err != orm.ErrNoRows {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			}
			if err == orm.ErrNoRows {
				area.UserId = sql.NullInt64{Valid: false}
				err = area.Update("user_id")
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
			} else {
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true}
				return
			}
		}
		if !area.UserId.Valid {
			manage := new(entity.Manager)
			err = manage.SelectAllByUserName(requestData.UserName)
			if err == orm.ErrNoRows {
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true}
				return
			} else if err != nil {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			} else {
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": false, "msg": "与其他账号重复"}
				return
			}
		}
	} else if requestData.AuthorityByte == entity.ManagerAuthority.School {
		school := new(entity.School)
		err = school.SelectAllById(requestData.Id)
		if err != nil {
			if err == orm.ErrNoRows {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
				return
			} else {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			}
		}
		if school.UserId.Valid {
			manage := new(entity.Manager)
			err = manage.SelectAllById(school.UserId.Int64)
			if err != nil && err != orm.ErrNoRows {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			}
			if err == orm.ErrNoRows {
				school.UserId = sql.NullInt64{Valid: false}
				err = school.Update("user_id")
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
			} else {
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true}
				return
			}
		}
		if !school.UserId.Valid {
			manage := new(entity.Manager)
			err = manage.SelectAllByUserName(requestData.UserName)
			if err == orm.ErrNoRows {
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true}
				return
			} else if err != nil {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			} else {
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": false, "msg": "与其他账号重复"}
				return
			}
		}
	} else if requestData.Authority == "all" && len(requestData.UserName) > 0 {
		manage := new(entity.Manager)
		err = manage.SelectAllByUserName(requestData.UserName)
		if err == orm.ErrNoRows {
			c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true}
			return
		} else if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		} else if manage.Id == requestData.Id {
			c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true}
			return
		} else {
			c.Data["json"] = map[string]interface{}{"retCode": 0, "result": false, "msg": "与其他账号重复"}
			return
		}
	}
}

func (c *UserController) GetCaptcha() {
	captchaId, ok := c.Ctx.Input.Session("cid").(string)
	if !ok {
		captchaId = captcha.NewLen(4)
	} else {
		if !captcha.Reload(captchaId) {
			captchaId = captcha.NewLen(4)
		}
	}
	c.SetSession("cid", captchaId)
	var content bytes.Buffer
	c.Ctx.ResponseWriter.Header().Set("Content-Type", "image/png")
	captcha.WriteImage(&content, captchaId, 99, 51)
	c.Ctx.ResponseWriter.ResponseWriter.Write(content.Bytes())
}

func (c *UserController) GetManagerList() {
	defer c.ServeJSON()
	userName := c.GetString("user-name")
	contactPhone := c.GetString("contact-phone")
	pageSize, err := c.GetInt64("page-size")
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	currentPage, err := c.GetInt64("current-page")
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	manage := new(entity.Manager)
	count, managerLists, err := manage.SelectManagerListByUserNameContactPhonePageSizeCurrentPage(userName, contactPhone, pageSize, currentPage)
	res := model.GetManagerListRes{RetCode: 0}
	res.Total = count
	res.Data = make([]model.ManagerList, len(managerLists))
	for i := 0; i < len(managerLists); i++ {
		res.Data[i].Id = managerLists[i].Id
		res.Data[i].UserName = managerLists[i].UserName
		if managerLists[i].Authority == entity.ManagerAuthority.Administrator {
			res.Data[i].Authority = "超级管理员"
		} else if managerLists[i].Authority == entity.ManagerAuthority.Area {
			res.Data[i].Authority = "区管理员"
			if len(managerLists[i].AreaName) != 0 {
				province := new(entity.Province)
				err = province.SelectAllById(managerLists[i].AreaProvinceId)
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
				city := new(entity.City)
				err = city.SelectAllById(managerLists[i].AreaCityId)
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
				res.Data[i].Object = province.Name + city.Name + managerLists[i].AreaName
				res.Data[i].Name = managerLists[i].AreaContact
			}
		} else if managerLists[i].Authority == entity.ManagerAuthority.School {
			if len(managerLists[i].SchoolName) != 0 {
				res.Data[i].Authority = "校管理员"
				province := new(entity.Province)
				err = province.SelectAllById(managerLists[i].SchoolProvinceId)
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
				city := new(entity.City)
				err = city.SelectAllById(managerLists[i].SchoolCityId)
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
				area := new(entity.Area)
				err = area.SelectAllById(managerLists[i].SchoolExperimentAreaId)
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
				res.Data[i].Object = province.Name + city.Name + area.Name + managerLists[i].SchoolName
				res.Data[i].Name = managerLists[i].SchoolContact
			}
		}
	}
	c.Data["json"] = res
}

func (c *UserController) PostPasswordModify() {
	defer c.ServeJSON()
	var requestData model.PostPasswordModifyArg
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestData)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
		return
	}
	b, err := requestData.Validate()
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
		return
	}
	manager := new(entity.Manager)
	err = manager.ChangePassword(requestData.Id, requestData.Password)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	nspel.RedisKeyDelete("manager")
	c.Data["json"] = map[string]interface{}{"retCode": 0, "msg": "更新成功"}
}

func (c *UserController) PostManagerModify() {
	defer c.ServeJSON()
	var requestData model.PostManagerModifyArg
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestData)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
		return
	}
	b, err, manager := requestData.Validate()
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
		return
	}
	manager.UserName = requestData.UserName
	err = manager.Update("user_name")
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	nspel.RedisKeyDelete("manager")
	if manager.Authority == entity.ManagerAuthority.Area {
		area := new(entity.Area)
		area.UserId = util.GetNullInt64(manager.Id, 0)
		area.Contact = util.GetNullString(requestData.Name)
		_, err = nspel.GetOrmEngine().QueryTable(area.TableName()).Filter("user_id", manager.Id).Update(orm.Params{"contact": requestData.Name})
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		nspel.RedisKeyDelete("area")
	} else if manager.Authority == entity.ManagerAuthority.School {
		school := new(entity.School)
		school.UserId = util.GetNullInt64(manager.Id, 0)
		school.Contact = util.GetNullString(requestData.Name)
		_, err = nspel.GetOrmEngine().QueryTable(school.TableName()).Filter("user_id", school.UserId).Update(orm.Params{"contact": school.Contact})
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		nspel.RedisKeyDelete("school")
	}
	c.Data["json"] = map[string]interface{}{"retCode": 0, "msg": "更新成功"}
}

func (c *UserController) PostUserHas() {
	defer c.ServeJSON()
	var requestData model.PostUserHasArg
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestData)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
		return
	}
	b, err, area, school := requestData.Validate()
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求错误"}
		return
	}
	if requestData.Type == "area" {
		if area.UserId.Valid {
			manager := new(entity.Manager)
			err = manager.SelectAllById(area.UserId.Int64)
			if err != nil && err != orm.ErrNoRows {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			} else if err == orm.ErrNoRows {
				area.UserId.Valid = false
				err = area.Update("user_id")
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": false, "msg": "不存在用户"}
			} else {
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true, "id": manager.Id}
			}
		} else {
			c.Data["json"] = map[string]interface{}{"retCode": 0, "result": false, "msg": "不存在用户"}
		}
	} else if requestData.Type == "school" {
		if school.UserId.Valid {
			manager := new(entity.Manager)
			err = manager.SelectAllById(school.UserId.Int64)
			if err != nil && err != orm.ErrNoRows {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			} else if err == orm.ErrNoRows {
				area.UserId.Valid = false
				err = area.Update("user_id")
				if err != nil {
					c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
					nspel.Error(err)
					return
				}
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": false, "msg": "不存在用户"}
			} else {
				c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true, "id": manager.Id}
			}
		} else {
			c.Data["json"] = map[string]interface{}{"retCode": 0, "result": false, "msg": "不存在用户"}
		}
	}
}
